//Ok start
//OK connected
//OK recv:
//OK  recv_login_resp 
//OK  recv_regular
//OK disconnected
//OK stop OK
//OK breakpoint get & set

use super::breakpoint::BreakPoint;
use super::message::Message;
use super::backend::Backend;


struct Service<'a> {
    breakpoint: BreakPoint,
    backend: &'a mut Backend
}

impl <'a> Service<'a> {
    fn ne(backend: &'a mut Backend) -> Service {
        Service { 
            breakpoint: BreakPoint::default(),
            backend 
        }
    }

    fn start(&mut self) -> bool {
        self.breakpoint.set(0);
        true
    }
    fn stop(&mut self) -> bool {
        self.breakpoint.set(0);
        true
    }

    fn breakpoint_mut(&mut self) -> &mut BreakPoint {
        &mut self.breakpoint
    }
    fn breakpoint(&self) -> &BreakPoint {
        &self.breakpoint
    }

    fn connected(&mut self) -> bool {
        self.backend.breakpoint_mut().set(self.breakpoint.get());
        true
    }

    fn backend(& self) -> &Backend{
        self.backend
    }

    fn disconnected(& self) -> bool {
        true
    }
    fn recv_login_resp(& self, login_response: Message) -> bool {
        if let Message::LoginResponse(ref _body) = login_response {
            return true;
        }
        false
    }
    fn recv_regular(&mut self, msg: Message) -> bool {
        match msg {
            Message::Order(seq_no, ref _body) =>  {
                if seq_no as u64 == self.breakpoint().get() + 1 {
                    self.breakpoint_mut().set(seq_no as u64);
                    return true;
                }
                return false;
            }
            Message::LoginResponse(ref _body)  =>  {
                return false;
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_service() {
        let mut backend = Backend::default();
        let mut s = Service::ne(&mut backend);
        assert!(s.start());
        assert_eq!(0u64, s.breakpoint().get());


        s.breakpoint_mut().set(2u64);
        assert_eq!(2u64, s.breakpoint().get());

        assert!(s.connected());
        assert_eq!(2u64, s.backend().breakpoint().get());

        assert!(s.recv_login_resp(Message::LoginResponse("login_resp".to_owned())));
        assert_eq!(2u64, s.breakpoint().get());

        assert!(s.recv_regular(Message::Order(3, "order3".to_owned())));
        assert_eq!(3u64, s.breakpoint().get());

        assert!(s.disconnected());

        assert!(s.stop());
        assert_eq!(0u64, s.breakpoint().get());
    }
}
